import { Injectable } from '@nestjs/common';
import {
  registerDecorator,
  ValidationArguments,
  ValidatorConstraint,
  ValidatorConstraintInterface,
  ValidatorOptions,
} from 'class-validator';
import { InjectRepository } from '@nestjs/typeorm';
import { User } from '../entities/user.entity';
import { Repository } from 'typeorm';

@Injectable()
@ValidatorConstraint({name:'startWith',async:false})
export class StartsWithConstraint implements ValidatorConstraintInterface {
  validate(
    value: any,
    validationArguments?: ValidationArguments,
  ): Promise<boolean> | boolean {
    const {constraints} = validationArguments
    return typeof value === 'string'&& value.startsWith(constraints[0])
  }

  defaultMessage(validationArguments?: ValidationArguments): string {
    const {property,constraints} = validationArguments

    return property+ ' must start with '+constraints[0]
  }
}

export function StartWith(prefix:string,validationOptions?:ValidatorOptions){
  return function(object:Object,propertyName:string){
    registerDecorator({
      target:object.constructor,//注册装饰器的目标类
      propertyName, //验证目标的属性名
      options:validationOptions, //验证选项
      constraints:[prefix],  //传递给验证器的参数 validationArguments  比如前缀
      validator:StartsWithConstraint
    })
  }
}

let userRepository = null

@Injectable()
@ValidatorConstraint({name:'IsUsernameUnique',async:true})
export class IsUsernameUniqueConstraint implements ValidatorConstraintInterface{

  constructor(@InjectRepository(User) private repository:Repository<User>) {
    if(!userRepository){
      userRepository = this.repository
    }
    console.log(this.repository);
  }

  defaultMessage(validationArguments?: ValidationArguments): string {
    const {property,value} = validationArguments
    return `${property} ${value} is already taken!`;
  }

  async validate(value: any, validationArguments?: ValidationArguments): Promise<boolean>  {
    const result = await userRepository.findOneBy({username:value})
    return !result;
  }

}

export function IsUsernameUnique(validationOptions?:ValidatorOptions){
  return function(object:Object,propertyName:string){
    registerDecorator({
      target:object.constructor,
      propertyName,
      options:validationOptions,
      constraints:[],
      validator:IsUsernameUniqueConstraint
    })
  }
}